package com.chat.service.Impl;

import BO.ChatPictureBO;
import BO.ReportBO;
import DO.chat.ChatDO;
import DO.chat.ChatPictureDO;
import DO.chat.ReportDO;
import DO.comments.CommentsDO;
import DTO.*;
import VO.ChatVO;
import VO.Feight.ChatByUserMsgVO;
import VO.Feight.UserMsgByChatVO;
import VO.RankingVO;
import VO.ReportSignVO;
import com.alibaba.fastjson.JSON;
import com.chat.mapper.*;
import com.chat.service.ChatService;
import Exception.ImageIsNotRightException;
import Exception.BaseException;
import Exception.ChatIsNotExistException;
import Exception.UserNotExistException;
import Exception.ExistCollectionChatException;
import Exception.ExistLikeChatException;
import Exception.NotLikeChatException;
import Exception.NotCollectionChatException;
import com.chat.service.RankingRedis;
import com.feign.clients.UserClient;
import constant.RedisPreKeyConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import result.Result;

import java.io.File;
import java.time.LocalDateTime;
import java.util.*;

import static com.utils.ImageUtils.*;
import static com.utils.RankingUtils.secondsRemaining;
import static com.utils.StringUtils.extractFilename;
import static com.utils.TimeUtils.formatTimeAgo;

@Service
@Slf4j
public class ChatServiceImpl implements ChatService {

    @Value("${ying_yan.chat_picture}")
    private String path;

    @Value("${ying_yan.report_picture}")
    private String reportPath;

    @Autowired
    private ChatMapper chatMapper;

    @Autowired
    private ChatPictureMapper chatPictureMapper;

    @Autowired
    private UserClient userClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private SignMapper signMapper;

    @Autowired
    private CollectionNumberMapper collectionNumberMapper;

    @Autowired
    private LikeMapper likeMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private ReportSignMapper reportSignMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private RankingRedis rankingRedis;

    // 帖子文件的保存
    @Transactional
    public void publishChat(String userId, PublishChatDTO publishChatDTO, MultipartFile[] files) {
        // 1. 先保存帖子主信息
        ChatDO chatDO = new ChatDO();
        chatDO.setTitle(publishChatDTO.getTitle());
        chatDO.setContent(publishChatDTO.getContent());
        chatDO.setUserId(Integer.valueOf(userId));
        chatDO.setPictureNumber(files==null?0:files.length);
        chatDO.setSignId(publishChatDTO.getSignId());
        chatDO.setCreatedTime(LocalDateTime.now());
        chatMapper.save(chatDO);

        // 2. 保存图片信息以及将图片保存到本地
        if (files==null||files.length==0){
            return;
        }
        int order = 1;
        List<ChatPictureDO> chatPictureDOList = new ArrayList<>();
        for (MultipartFile file : files) {
            // 3.1 对图片文件进行校验
            if (!isSafeImageFile(file)){
                // 表示这个图片不安全或者不是图片文件
                throw new ImageIsNotRightException();
            }
            // 3.2 对图片文件进行保存
            // 文件名称 chat_picture 用户id + 帖子id + 顺序 例如：chat_picture_1_21_1
            String newFileName = "chat_picture_" + userId + "_" + chatDO.getId() + "_" + order;
            saveMultipartFile(file,path,newFileName);

            // 3.3 计算文件的宽高
            Integer[] imageSize = measureImageSize(file);
            if (imageSize==null){
                // 表示文件解析失败,返回网络错误
                throw new BaseException();
            }

            // 3.4 保存数据
            ChatPictureDO chatPictureDO = new ChatPictureDO();
            chatPictureDO.setChatId(chatDO.getId());
            chatPictureDO.setCreatedTime(LocalDateTime.now());
            chatPictureDO.setOrder(order);

            String originalFilename = file.getOriginalFilename();
            String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));

            chatPictureDO.setAddress(path+ File.separator + newFileName + fileExtension);
            chatPictureDO.setHeight(imageSize[0]);
            chatPictureDO.setWidth(imageSize[1]);
            chatPictureDOList.add(chatPictureDO);
            order++;
        }

        chatPictureMapper.save(chatPictureDOList);
    }

    // 帖子数量的获取
    public UserMsgByChatVO getChatNumberByUserId(Integer userId) {
        UserMsgByChatVO userMsgByChatVO = new UserMsgByChatVO();
        // 作品数
        userMsgByChatVO.setChatNumber(chatMapper.getChatNumberByUserId(userId));

        // 作品点赞数
        List<Integer> likeNUmber = chatMapper.getLikeNumberByUserId(userId);
        int a = 0;
        for (Integer i : likeNUmber) {
            a = a + i;
        }
        userMsgByChatVO.setChatLikeNumber(a);
        return userMsgByChatVO;
    }

    // 获取帖子id数组
    public List<Integer> getChatIdArray(ChatPageDTO chatPageDTO) {
        return chatMapper.getChatIdArray(chatPageDTO);
    }

    // 根据id获取帖子信息
    public ChatVO getChatById(Integer chatId, Integer userId) {
        ChatVO chatVO = new ChatVO();

        // 1. 从redis中获取帖子数据
        String chatVo = stringRedisTemplate.opsForValue().get(RedisPreKeyConstant.CHAT_MSG + chatId);

        if (chatVo!=null){
            //  1.1 redis中有数据
            chatVO = JSON.parseObject(chatVo, ChatVO.class);
        }else {
            // 1.2 redis中没有数据
            ChatDO chatDO = chatMapper.getById(chatId);
            if (chatDO==null){
                // 表示帖子不存在
                throw new ChatIsNotExistException("帖子不存在");
            }

            BeanUtils.copyProperties(chatDO,chatVO);
            chatVO.setChatId(chatDO.getId());
            // 1.3 根据signIid获取具体的sign
            chatVO.setSign(signMapper.getSignById(chatDO.getSignId()));

            List<ChatPictureDO> chatPictureDOList = chatPictureMapper.getByChatId(chatId);
            List<ChatPictureBO> chatPictureBOList = new ArrayList<>();
            for (ChatPictureDO chatPictureDO : chatPictureDOList) {
                ChatPictureBO chatPictureBO = new ChatPictureBO();

                chatPictureBO.setAddress(extractFilename(chatPictureDO.getAddress()));
                chatPictureBO.setOrder(chatPictureDO.getOrder());
                chatPictureBO.setWidth(chatPictureDO.getWidth());
                chatPictureBO.setHeight(chatPictureDO.getHeight());

                chatPictureBOList.add(chatPictureBO);
            }

            chatVO.setChatPictureBOList(chatPictureBOList);

            // 1.4 将数据缓存到redis中
            stringRedisTemplate.opsForValue().set(RedisPreKeyConstant.CHAT_MSG + chatId,JSON.toJSONString(chatVO));
        }

        // 2. 对时间进行处理
        chatVO.setTime(formatTimeAgo(chatVO.getCreatedTime()));

        // 远程调用
        Result<ChatByUserMsgVO> chatUserMsg = userClient.getChatUserMsg(chatVO.getUserId(), userId);
        if (chatUserMsg.getCode()==201){
            // 表示发帖人不存在
            chatVO.setUsername("发帖人不存在");
            // 设置为-1 告诉前端这个发帖人不存在（发表不良言论被删除了），TODO 同时后端也需要删除这个人的帖子信息
            chatVO.setFollow(-1);
        }else{
            chatVO.setUsername(chatUserMsg.getData().getUsername());
            chatVO.setFollow(chatUserMsg.getData().getFollow());
        }

        // 补充是否点赞，收藏
        if (userId == 0){
            // 表示没有用户登录
            chatVO.setLike(0);
            chatVO.setCollection(0);
        }else {
            chatVO.setCollection(collectionNumberMapper.getByChatIdAndUserId(chatId,userId));
            chatVO.setLike(likeMapper.getByChatIdAndUserId(chatId,userId));
        }
        return chatVO;
    }

    // 用户收藏
    @Transactional
    public void collectionById(String userId, Integer chatId) {
        // 1. 判断这个userId，chatId 是否存在
        if (!userClient.findById(Integer.valueOf(userId))){
            // 抛出用户不存在异常
            throw new UserNotExistException();
        }

        // 2. 判断帖子是否存在
        if (chatMapper.getById(chatId)==null){
            // chatDO 为null 表示帖子不存在
            throw new ChatIsNotExistException();
        }

        // 3. 判断收藏表中有无数据
        if (collectionNumberMapper.getByChatIdAndUserId(chatId, Integer.valueOf(userId))==1){
            throw new ExistCollectionChatException();
        }

        // 4. 向数据库写入数据
        chatMapper.updateChatCollection(chatId);
        collectionNumberMapper.save(chatId, Integer.valueOf(userId),LocalDateTime.now());

        // 5.删除redis中的这个数据
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG + chatId);

        // 6. 补充排行榜信息
        rankingRedis.collectionChat(chatId);
    }

    // 用户点赞帖子
    @Transactional
    public void like(Integer userId, Integer chatId) {
        // 1. 判断这个userId，chatId 是否存在
        if (!userClient.findById(userId)){
            // 抛出用户不存在异常
            throw new UserNotExistException();
        }

        // 2. 判断帖子是否存在 TODO 后面利用这个chatDO修改redis的缓存
        if (chatMapper.getById(chatId)==null){
            // chatDO 为null 表示帖子不存在
            throw new ChatIsNotExistException();
        }

        // 3. 判断点赞表中有无数据
        if (likeMapper.getByChatIdAndUserId(chatId, userId)==1){
            throw new ExistLikeChatException();
        }

        // 4. 向数据库写入数据
        chatMapper.updateChatLike(chatId);
        likeMapper.save(chatId, userId,LocalDateTime.now());

        // 5.删除redis中的这个数据
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG + chatId);

        // 6. 补充排行榜数据
        rankingRedis.likeChat(chatId);
    }

    // 用户取消收藏
    @Transactional
    public void deleteCollectionById(Integer userId, Integer chatId) {
        // 1. 判断这个userId，chatId 是否存在
        if (!userClient.findById(userId)){
            // 抛出用户不存在异常
            throw new UserNotExistException();
        }

        // 2. 判断帖子是否存在
        if (chatMapper.getById(chatId)==null){
            // chatDO 为null 表示帖子不存在
            throw new ChatIsNotExistException();
        }

        // 3. 判断收藏表中有无数据
        if (collectionNumberMapper.getByChatIdAndUserId(chatId, userId)==0){
            // 该用户对帖子没有收藏关系
            throw new NotCollectionChatException();
        }

        // 4. 删除收藏消息
        chatMapper.DeleteChatCollection(chatId);
        collectionNumberMapper.delete(chatId, userId);

        // 5. 删除redis中的数据
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG + chatId);

        // 6. 更新排行榜
        rankingRedis.clCollectionChat(chatId);
    }

    // 用户取消点赞
    @Transactional
    public void deleteLike(Integer userId, Integer chatId) {
        // 1. 判断这个userId，chatId 是否存在
        if (!userClient.findById(userId)){
            // 抛出用户不存在异常
            throw new UserNotExistException();
        }

        // 2. 判断帖子是否存在 TODO 后面利用这个chatDO修改redis的缓存
        if (chatMapper.getById(chatId)==null){
            // chatDO 为null 表示帖子不存在
            throw new ChatIsNotExistException();
        }

        // 3. 判断点赞表中有无数据
        if (likeMapper.getByChatIdAndUserId(chatId, userId)==0){
            throw new NotLikeChatException();
        }

        // 4. 删除数据库的数据
        chatMapper.deleteChatLike(chatId);
        likeMapper.delete(chatId, userId);

        // 5.删除redis中的这个数据
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG + chatId);

        // 6. 更新用户点赞
        rankingRedis.clLikeChat(chatId);
    }

    // 用户评论
    public void pubChatComment(PubCommentDTO pubCommentDTO, Integer userId) {
        // 1. 判断帖子是否存在
        ChatDO chatDO = chatMapper.getById(pubCommentDTO.getChatId());
        if (chatDO == null){
            // 表示帖子不存在
            throw new ChatIsNotExistException();
        }
        // 2. 发送mq消息给评论服务保存用户的评论
        CommentsDO commentsDO = new CommentsDO();
        BeanUtils.copyProperties(pubCommentDTO,commentsDO);
        // 发帖人id
        commentsDO.setChatUserId(chatDO.getUserId());
        // 评论人
        commentsDO.setUserId(userId);
        // 是否是顶级评论
        commentsDO.setIsFirst(pubCommentDTO.getIsRoot());

        if (pubCommentDTO.getIsRoot() == 0){ // 表示不是顶级评论
            // 目标评论id
            commentsDO.setToCommentId(pubCommentDTO.getGoalId());
            // 目标评论的发帖人id 在comments表中查询
        }
        try {
            rabbitTemplate.convertAndSend("ying.yan", "chat.save.comments", commentsDO);
        } catch (Exception e) {
            log.error("评论消息发送失败，评论人id:{},评论内容是：{}，评论帖子是：{}，" +
                    "顶级评论：{}，顶级评论id：{}，目标评论：{}。",
                    commentsDO.getUserId(),commentsDO.getContent(),commentsDO.getChatId(),commentsDO.getIsFirst(),
                    commentsDO.getRootCommentsId(),commentsDO.getToCommentId());
        }

        // 3. 如果消息发送成功，则需要将这个帖子的评论数+1
        chatMapper.updateChatComments(pubCommentDTO.getChatId());

        // 4. 由于评论数据更改，将这个redis中的数据删除
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG + pubCommentDTO.getChatId());

        // 5. 补充排行榜数据
        rankingRedis.commentChat(chatDO.getId());
    }

    // 获取用户发帖id
    public List<Integer> getUserPubChatId(ChatPageByUserPubDTO chatPageByUserPubDTO) {
        return chatMapper.getUserPubChatId(chatPageByUserPubDTO);
    }

    // 获取用户的收藏id
    public List<Integer> getUserChatIdByCollection(ChatPageByCollectionDTO chatPageByCollectionDTO) {
        return collectionNumberMapper.getUserChatIdByCollection(chatPageByCollectionDTO);
    }

    // 用户删除帖子
    public void deleteChat(Integer userId, Integer chatId) {
        // 1. 判断该帖子是否存在以及是否属于这个人
        ChatDO chatDO = chatMapper.getById(chatId);
        if (chatDO==null||!Objects.equals(chatDO.getUserId(), userId)){
            // 帖子不存在或者帖子不属于这个人
            throw new ChatIsNotExistException();
        }

        // 2. 删除帖子
        chatMapper.deleteChatById(chatId);

        // 3-1 给自己服务发消息，删除自己的数据
        rabbitTemplate.convertAndSend("ying.yan.delete", "chat.delete", chatId);
        // 3-2 给评论模块发消息，删除帖子的评论数据
        rabbitTemplate.convertAndSend("ying.yan.deleteComment", "chat.delete.comments", chatId);

        // 4. 删除帖子的redis数据
        stringRedisTemplate.delete(RedisPreKeyConstant.CHAT_MSG+chatId);
    }

    // 用户举报帖子
    public void reportChat(ReportChatDTO reportChatDTO, String userId, MultipartFile[] files) {
        // 1.判断图片格式是否正确
        for (MultipartFile file : files) {
            if (!isSafeImageFile(file)){
                // 51 图片格式不正确
                throw new ImageIsNotRightException();
            }
        }

        // 2. 检查帖子是否存在
        ChatDO chatDO = chatMapper.getById(reportChatDTO.getChatId());
        if (chatDO==null){
            // 帖子不存在
            throw new ChatIsNotExistException();
        }

        // 3. 保存举报数据
        ReportDO reportDO = new ReportDO();
        reportDO.setChatId(reportChatDTO.getChatId());
        reportDO.setUserId(Integer.valueOf(userId));
        reportDO.setReportReason(reportChatDTO.getContent());
        reportDO.setCreatedTime(LocalDateTime.now());
        reportDO.setReportSign(reportChatDTO.getReportSign());

        for (int i = 0; i < files.length; i++) {
            if (i==0){
                // 1. 构建文件名
                String newFileName = UUID.randomUUID().toString();

                // 2. 保存文件
                saveMultipartFile(files[i],reportPath, newFileName);
                String originalFilename = files[i].getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));

                // 3. 获取文件相对地址
                String path = reportPath + File.separator + newFileName +  fileExtension;
                reportDO.setPicture1(path);
            }
            else if (i==1){
                // 1. 构建文件名
                String newFileName = UUID.randomUUID().toString();

                // 2. 保存文件
                saveMultipartFile(files[i],reportPath, newFileName);
                String originalFilename = files[i].getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));

                // 3. 获取文件相对地址
                String path = reportPath + File.separator + newFileName +  fileExtension;
                reportDO.setPicture2(path);
            }
            else if (i==2){
                // 1. 构建文件名
                String newFileName = UUID.randomUUID().toString();

                // 2. 保存文件
                saveMultipartFile(files[i],reportPath, newFileName);
                String originalFilename = files[i].getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));

                // 3. 获取文件相对地址
                String path = reportPath + File.separator + newFileName +  fileExtension;
                reportDO.setPicture2(path);
            }
            else if (i==3){
                // 1. 构建文件名
                String newFileName = UUID.randomUUID().toString();

                // 2. 保存文件
                saveMultipartFile(files[i],reportPath, newFileName);
                String originalFilename = files[i].getOriginalFilename();
                String fileExtension = originalFilename.substring(originalFilename.lastIndexOf('.'));

                // 3. 获取文件相对地址
                String path = reportPath + File.separator + newFileName +  fileExtension;
                reportDO.setPicture3(path);
            }
        }

        reportMapper.save(reportDO);
    }

    // 获取举报标签
    public ReportSignVO getReportSign() {
        ReportSignVO reportSignVO = new ReportSignVO();
        // 1. 从redis中获取帖子数据
        String reportSignString = stringRedisTemplate.opsForValue().get(RedisPreKeyConstant.REPORT_SIGN);

        if (reportSignString!=null){
            //  1.1 redis中有数据
            reportSignVO = JSON.parseObject(reportSignString, ReportSignVO.class);
        }else {
            // 一级标签
            List<ReportBO> first = reportSignMapper.getFirst();
            reportSignVO.setFirst(first);

            // 二级标签
            List<List<ReportBO>> second = new ArrayList<>();
            for (int i = 0; i < first.size(); i++) {
                List<ReportBO> secondById = reportSignMapper.getSecond(i + 1);
                second.add(secondById);
            }
            reportSignVO.setSecond(second);

            // 将数据缓存到redis中
            stringRedisTemplate.opsForValue().set(RedisPreKeyConstant.REPORT_SIGN,JSON.toJSONString(reportSignVO));
        }

        return reportSignVO;
    }

    // 删除收藏数据
    public void MQdeleteCollection(Integer chatId) {
        collectionNumberMapper.deleteByChatId(chatId);
    }

    // 删除帖子点赞数据
    public void MQdeleteLike(Integer chatId) {
        likeMapper.deleteByChatId(chatId);
    }

    // 删除图片数据
    public void MqdeletePicture(Integer chatId) {
        // 1. 先查询这个帖子有多少图片
        List<ChatPictureDO> chatPictureDOList = chatPictureMapper.getByChatId(chatId);
        for (ChatPictureDO chatPictureDO : chatPictureDOList) {
            // 构造File对象
            File file = new File(chatPictureDO.getAddress());

            // 尝试删除文件
            if (!deleteFile(file)){
                log.error("删除文件失败: " + file.getAbsolutePath());
                if (!file.exists()) {
                    log.info("文件不存在: " + file.getAbsolutePath());
                } else {
                    // 文件存在但删除失败（可能是因为权限或其他原因）
                    log.info("文件存在但无法删除: " + file.getAbsolutePath());
                }
            }

        }

        chatPictureMapper.deleteByChat(chatId);

    }

    // 获取排行榜数据
    public List<RankingVO> getRanking(RankingChatDTO rankingChatDTO) {
        // 1. 先从redis中获取数据
        // 获取ZSetOperations实例
        ZSetOperations<String, Object> zSetOperations = redisTemplate.opsForZSet();

        String key = "";
        // 定义key、起始分数、结束分数、偏移量和要获取的数量
        switch (rankingChatDTO.getType()){
            case 1:
                key = RedisPreKeyConstant.RANKING_DAY;
                break;
            case 2:
                key = RedisPreKeyConstant.RANKING_WEEK;
                break;
            case 3:
                key = RedisPreKeyConstant.RANKING_MONTH;
                break;
        }
        double startScore = Double.NEGATIVE_INFINITY; // 起始分数，这里使用负无穷大表示从最低分数开始
        double endScore = Double.POSITIVE_INFINITY; // 结束分数，这里使用正无穷大表示到最高分数结束
        long offset = rankingChatDTO.getNumber(); // 偏移量，即跳过前number个元素
        long count = rankingChatDTO.getChatNumber(); // 要获取的数量

        // 使用ZREVRANGEBYSCORE命令并加上LIMIT选项来获取数据
        Set<ZSetOperations.TypedTuple<Object>> tuples = zSetOperations.reverseRangeByScoreWithScores(key, startScore, endScore, offset, count);

        // 2. 整合数据 如果该id是-1 表示帖子是已经删除的
        List<RankingVO> rankingVOList = new ArrayList<>();
        if (tuples != null) {
            for (ZSetOperations.TypedTuple<Object> tuple : tuples) {
                RankingVO rankingVO = new RankingVO();
                String[] parts = Objects.requireNonNull(tuple.getValue()).toString().split("_"); // 使用 "_" 作为分隔符拆分字符串

                long longPart = Long.parseLong(parts[0]); // 将第一部分转换为 long, 秒数
                int integerPart = Integer.parseInt(parts[1]); // 将第二部分转换为 int 帖子id
                rankingVO.setId(integerPart);
                rankingVO.setScore(tuple.getScore());

                // 判断是否过期
                int days = 0;
                if (rankingChatDTO.getType() ==1){
                    days = 1;
                } else if (rankingChatDTO.getType() == 2) {
                    days = 7;
                } else if (rankingChatDTO.getType() == 3) {
                    days = 30;
                }
                if (!secondsRemaining(longPart,days)){
                    // 表示已经过期了,删除redis中的这个值
                    zSetOperations.remove(key, tuple.getValue());
                }

                // 根据这个帖子id获取该帖子的标题
                ChatVO chatVO = new ChatVO();

                // 从redis中获取帖子数据
                String chatVo = stringRedisTemplate.opsForValue().get(RedisPreKeyConstant.CHAT_MSG + integerPart);

                if (chatVo!=null){
                    //  1.1 redis中有数据
                    chatVO = JSON.parseObject(chatVo, ChatVO.class);
                }else {
                    // 1.2 redis中没有数据
                    ChatDO chatDO = chatMapper.getById(integerPart);
                    if (chatDO == null) {
                        // 表示帖子不存在
                        rankingVO.setId(-1);
                        zSetOperations.remove(key, tuple.getValue());
                        break;
                    }

                    BeanUtils.copyProperties(chatDO, chatVO);
                    chatVO.setChatId(chatDO.getId());
                    // 1.3 根据signIid获取具体的sign
                    chatVO.setSign(signMapper.getSignById(chatDO.getSignId()));

                    List<ChatPictureDO> chatPictureDOList = chatPictureMapper.getByChatId(integerPart);
                    List<ChatPictureBO> chatPictureBOList = new ArrayList<>();
                    for (ChatPictureDO chatPictureDO : chatPictureDOList) {
                        ChatPictureBO chatPictureBO = new ChatPictureBO();

                        chatPictureBO.setAddress(extractFilename(chatPictureDO.getAddress()));
                        chatPictureBO.setOrder(chatPictureDO.getOrder());
                        chatPictureBO.setWidth(chatPictureDO.getWidth());
                        chatPictureBO.setHeight(chatPictureDO.getHeight());

                        chatPictureBOList.add(chatPictureBO);
                    }

                    chatVO.setChatPictureBOList(chatPictureBOList);

                    // 1.4 将数据缓存到redis中
                    stringRedisTemplate.opsForValue().set(RedisPreKeyConstant.CHAT_MSG + integerPart, JSON.toJSONString(chatVO));
                }

                rankingVO.setTitle(chatVO.getTitle());

                rankingVOList.add(rankingVO);
            }
        }

        return rankingVOList;
    }

    // 删除评论
    public void MQupdateComment(Integer chatId, Integer number) {
        chatMapper.deleteComment(chatId,number);
    }
}
